#ifndef SHENLAN_SIMPLE_FUNCTION
#define SHENLAN_SIMPLE_FUNCTION
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#ifdef UNITY_COLORSPACE_GAMMA
    #define unity_ColorSpaceGrey fixed4(0.5, 0.5, 0.5, 0.5)
    #define unity_ColorSpaceDouble fixed4(2.0, 2.0, 2.0, 2.0)
    #define unity_ColorSpaceDielectricSpec half4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301)
    #define unity_ColorSpaceLuminance half4(0.22, 0.707, 0.071, 0.0) // Legacy: alpha is set to 0.0 to specify gamma mode
#else // Linear values
    #define unity_ColorSpaceGrey fixed4(0.214041144, 0.214041144, 0.214041144, 0.5)
    #define unity_ColorSpaceDouble fixed4(4.59479380, 4.59479380, 4.59479380, 2.0)
    #define unity_ColorSpaceDielectricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) // standard dielectric reflectivity coef at incident angle (= 4%)
    #define unity_ColorSpaceLuminance half4(0.0396819152, 0.458021790, 0.00609653955, 1.0) // Legacy: alpha is set to 1.0 to specify linear mode
#endif

#if _STYLIZATIONMOSTER_ON | _STYLIZATIONMOSTER2_ON | _STYLIZATIONMOSTER3_ON | _STYLIZATIONMOSTER4_ON | _STYLE_RAIN_STORM_ON | _STYLIZATIONPLAYER_ON | _STYLE_JOINT_ON | _STYLE_ASSIST_ON | _STYLE_SHADOW_ON
    #define STY_UV4 float4 uv4:TEXCOORD4;
    #if _STYLIZATIONMOSTER_ON
        #define STY_VERT(posWorld)\
        o.uv4 = float4(v.vertex.xy * 8.7 + float2(16, 5), float2(0.005, 0.003) * _Time.y);
    #elif _STYLIZATIONMOSTER2_ON
        #define STY_VERT(posWorld)\
        float2 styPath = lerp(float2(-0.04, 0.04), float2(-0.15, 0.05), _StyOffset.x); \
        o.uv4 = float4(-v.vertex.xy * 8.7 * styPath, abs(frac((v.vertex.xx + v.vertex.yy * 0.5) * 0.35 + 0.3) - 0.5) * 3 + 0.8);
    #elif _STYLIZATIONMOSTER3_ON
        #define STY_VERT(posWorld)\
        o.uv4 = float4(-v.vertex.xy * 8.7 * float4(0.15, 0.2, 0.15, 0.2) * 0.02, -0.1 * _Time.yy);
    #elif _STYLE_RAIN_STORM_ON
        #define STY_VERT(posWorld)\
        o.uv4 = float4(v.vertex.xy, 0, 0);
    #elif _STYLE_JOINT_ON
        #define STY_VERT(posWorld)\
        o.uv4 = float4(-v.vertex.xy * 0.1, frac(_Time.y * 0.2), frac(_Time.y * 0.2 + 0.5));
    #elif _STYLE_ASSIST_ON
        #define STY_VERT(posWorld)\
        o.uv4 = float4(v.vertex.xy, float2(0.005, 0.003) * _Time.y);
    #elif _STYLIZATIONMOSTER4_ON
        #define STY_VERT(posWorld)\
        o.uv4 = float4(v.vertex.xy*float2(0.05,0.8), v.vertex.y, 0);
    #elif _STYLE_SHADOW_ON
        #define STY_VERT(posWorld)\
            o.uv4 = v.vertex.yyyy;
    #else //橘子树场景
        #define STY_VERT(posWorld)\
        o.uv4 = posWorld.xyxy * float4(0.82, 2, 2.5, 2.5); \
        o.uv4 = Anim_Sequence_frame2(floor(_Time.y * 4), 4, 4, o.uv4); //速度：1.3 行列：(4,4)
    #endif
#else
    #define STY_UV4
    #define STY_VERT(posWorld)
#endif


//旋转矩阵(提供角度)
float2x2 RotateMatrix(float Angle)
{
    float ra = radians(Angle);
    float2 cs = float2(cos(ra), sin(ra));
    float2x2 m = float2x2(cs.x, cs.y, -cs.y, cs.x);
    return m;
}

//旋转矩阵(提供向量)
float2x2 RotateMatrix(float2 Dir)
{
    float2x2 m = float2x2(Dir.x, Dir.y, -Dir.y, Dir.x);
    return m;
}


//旋转矩阵3轴
float3x3 RotateMatrix3Radian(float radian_, float3 axis_)
{
    float c = cos(radian_);
    float s = sin(radian_);
    float3 a = axis_;
    float3x3 m = float3x3(
        a.x * a.x * (1 - c) + c, a.x * a.y * (1 - c) - a.z * s, a.x * a.z * (1 - c) + a.y * s,
        a.x * a.y * (1 - c) + a.z * s, a.y * a.y * (1 - c) + c, a.y * a.z * (1 - c) - a.x * s,
        a.x * a.z * (1 - c) - a.y * s, a.y * a.z * (1 - c) + a.x * s, a.z * a.z * (1 - c) + c
    );
    return m;
}

float3x3 RotateMatrix3(float angle, float3 a)
{
    return RotateMatrix3Radian(radians(angle), a);
}

//转化之后的齐次裁剪坐标
//基于屏幕空间缩放，缩放中心为左下角，在后处理Mask中使用(透视相机)
//posView顶点的视线坐标，size缩放尺寸，uvOffset偏移半屏单位(例:float2(1,2)则往右偏移1个半屏单位，往上偏移2个半屏单位)
float4 VertexPosViewSpaceScale(float3 posView, float2 size, float2 uvOffset, out float2 center)
{
    float tanFovHalf = abs(UNITY_MATRIX_P._22);
    //float fov = radians(35);
    float center_Y = posView.z / tanFovHalf;
    float center_X = center_Y * (_ScreenParams.x / _ScreenParams.y); //(_ScreenParams.x / _ScreenParams.y)屏幕宽高比，
    center = float2(center_X, center_Y); //屏幕左下方坐标
    posView.xy = (posView.xy - center) * size + center - center * uvOffset; //以屏幕左下方坐标为中心进行缩放
    float4 posCS = mul(UNITY_MATRIX_P, float4(posView, 1));
    return posCS;
}

//转化之后的视线空间坐标
//基于屏幕空间缩放，缩放中心为左下角，在后处理Mask中使用(透视相机)
//posView顶点的视线坐标，size缩放尺寸，uvOffset偏移半屏单位(例:float2(1,2)则往右偏移1个半屏单位，往上偏移2个半屏单位)
float4 VertexPosViewSpaceScale_ViewPos(float3 posView, float2 size, float2 uvOffset, out float2 center, float matrix_p_22, float ascept)
{
    float tanFovHalf = abs(matrix_p_22);
    //float fov = radians(35);
    float center_Y = posView.z / tanFovHalf;
    float center_X = center_Y * ascept; //(_ScreenParams.x / _ScreenParams.y)屏幕宽高比，
    center = float2(center_X, center_Y); //屏幕左下方坐标
    posView.xy = (posView.xy - center) * size + center - center * uvOffset; //以屏幕左下方坐标为中心进行缩放
    float4 posCS = float4(posView, 1);
    return posCS;
}

//转化之后的齐次裁剪坐标（UI用）
//基于屏幕空间缩放，缩放中心为左下角，在后处理Mask中使用(正交相机)
//posView顶点的视线坐标，size缩放尺寸，uvOffset偏移半屏单位(例:float2(1,2)则往右偏移1个半屏单位，往上偏移2个半屏单位)
float4 VertexPosViewSpaceScaleUI(float3 posView, float2 size, float2 uvOffset, out float2 center)
{
    float center_Y = unity_OrthoParams.y; //正交屏幕高
    float center_X = unity_OrthoParams.x; //正交屏幕宽
    center = float2(center_X, center_Y);
    posView.xy = (posView.xy - center) * size + center * uvOffset;
    float4 posCS = mul(UNITY_MATRIX_P, float4(posView, 1));
    return posCS;
}

//序列帧动画
float2 Anim_Sequence_frame(float frame_id, float frame_SizeX, float frame_SizeY, float2 frame_UV)
{
    float idv = floor(frame_id / frame_SizeX);
    float idu = frame_id - idv * frame_SizeX;
    float stepU = 1.0 / frame_SizeX;
    float stepV = 1.0 / frame_SizeY;
    float2 initUV = frame_UV * float2(stepU, stepV) + float2(0.0, stepV * (frame_SizeY - 1));
    float2 newUV = initUV + float2(idu * stepU, -idv * stepV);
    return newUV;
}

//序列帧动画
float4 Anim_Sequence_frame2(float frame_id, float frame_SizeX, float frame_SizeY, float4 frame_UV)
{
    float idv = floor(frame_id / frame_SizeX);
    float idu = frame_id - idv * frame_SizeX;
    float stepU = 1.0 / frame_SizeX;
    float stepV = 1.0 / frame_SizeY;
    float4 step4 = float4(stepU, stepV, stepU, stepV);
    float frameIndex = stepV * (frame_SizeY - 1);
    float4 initUV = frame_UV * step4 + float4(0.0, frameIndex, 0.0, frameIndex);
    float4 newUV = initUV + float4(idu * stepU, -idv * stepV, idu * stepU, -idv * stepV);
    return newUV;
}

float3 ScreenMask(float3 posView, float4 tex_ST)
{
    float tanFovHalf = abs(UNITY_MATRIX_P._22);
    float center_Y = posView.z / tanFovHalf;
    float center_X = center_Y * (_ScreenParams.x / _ScreenParams.y); //(_ScreenParams.x / _ScreenParams.y)屏幕宽高比，
    float3 newPos = posView;
    newPos.xy = -0.5 * posView.xy * tex_ST.xy / float2(center_X, center_Y) - tex_ST.zw + 0.5;
    return newPos;
}

//屏幕传入材质时的UV
float2 ScreenColorTexUV(float3 posView)
{
    float tanFovHalf = abs(UNITY_MATRIX_P._22);
    float newY = -posView.z / tanFovHalf;
    float newX = newY * (_ScreenParams.x / _ScreenParams.y);
    float2 newUV = float2(newX, newY);
    newUV = (posView.xy / newUV) * 0.5 + 0.5;
    return newUV;
}

//标准模型的4个顶点铺面屏幕
float4 View_BackGround_Plane_SignVertex(float3 signVertex, float posZRan, float4 offset)
{
    float2 center_XY = 1 / abs(UNITY_MATRIX_P._11_22); //获得tan(FOV/2)
    float3 posView = float3(center_XY, -1) * posZRan * signVertex; //根据FarNearPlaneHight = 2*tan(FOV/2)*Far 获得屏幕边上的顶点位置
    posView.xy = posView.xy * offset.z + offset.xy; //缩放和偏移
    float4 newVertex = mul(UNITY_MATRIX_P, float4(posView, 1));
    return newVertex;
}

//标准模型的4个顶点铺面屏幕(带旋转)
float4 View_BackGround_Plane_SignVertex_Round(float3 signVertex, float posZRan, float4 offset)
{
    float2 center_XY = 1 / abs(UNITY_MATRIX_P._11_22); //获得tan(FOV/2)
    float3 posView = float3(center_XY, -1) * posZRan * signVertex; //根据FarNearPlaneHight = 2*tan(FOV/2)*Far 获得屏幕边上的顶点位置
    posView.xy = mul(RotateMatrix(offset.w), posView.xy);
    posView.xy = posView.xy * offset.z + offset.xy; //缩放和偏移
    float4 newVertex = mul(UNITY_MATRIX_P, float4(posView, 1));
    return newVertex;
}

//标准模型的4个顶点铺面屏幕
float4 View_BackGround_Plane(float4 posVertex, float posZRan, float4 offset)
{
    float3 signVertex = sign(float3(posVertex.xy, 1)); //取模型的正负值
    return View_BackGround_Plane_SignVertex(signVertex, posZRan, offset);
}

//标准模型的4个顶点铺面屏幕
float4 View_BackGround_Plane_Round(float4 posVertex, float posZRan, float4 offset)
{
    float3 signVertex = sign(float3(posVertex.xy, 1)); //取模型的正负值
    return View_BackGround_Plane_SignVertex_Round(signVertex, posZRan, offset);
}

//粒子系统的4个顶点铺面屏幕
float4 View_BackGround_Plane(float vertexID, float posZRan, float4 offset)
{
    float signY = 1 - floor(vertexID * 0.5) * 2; //根据顶点的ID获得上-1，下1的值
    float signX = saturate(2 - abs(vertexID - 1.5) * 2) * 2 - 1; //根据顶点的ID获得左-1，右1的值
    float3 signVertex = float3(signX, signY, 1); //取模型的正负值
    return View_BackGround_Plane_SignVertex(signVertex, posZRan, offset);
}


///顶点的屏幕适配
float Vertex_ScreenAdaptation(float x)
{
    float percent = (1080.0 / 1920.0) * ((float)_ScreenParams.x / (float)_ScreenParams.y);
    return x * percent;
}

///极坐标
half4 PolarUV(half4 uv)
{
    half4 ligpos = uv - 0.5;
    half2 radial = half2(length(ligpos.xy), length(ligpos.zw));
    half2 rotate = half2(atan2(ligpos.x, ligpos.y), atan2(ligpos.z, ligpos.w)) / TWO_PI + 0.5;
    half4 uvNew = half4(radial.x, rotate.x, radial.y, rotate.y);
    return uvNew;
}

half2 PolarUV(half2 uv)
{
    half2 ligpos = uv - 0.5;
    half radial = length(ligpos.xy);
    half rotate = atan2(ligpos.x, ligpos.y) / TWO_PI + 0.5;
    half2 uvNew = half2(radial, rotate);
    return uvNew;
}


//timeCustom可以是自定义时间，也可以是_Time.y
float3 SheetUV(half2 sheetIndex, float4 mainTex_ST, float2 uv, float speed, float timeCustom, float loopOrOnce)
{
    float2 offset = float2(1.0 / sheetIndex.x, 1.0 / sheetIndex.y);
    float2 uv_temp = (uv - 0.5) * mainTex_ST.xy + 0.5 + mainTex_ST.zw;
    float t = timeCustom * speed;
    float3 f = floor(float3(t, t * offset.x, t * offset.x * offset.y)); //UV根据行列数对号入座
    float2 num = float2(f.x - sheetIndex.x * f.y, f.y + sheetIndex.y * f.z);
    float3 newUV = float3((uv_temp.x + num.x) * offset.x, (uv_temp.y - num.y - 1) * offset.y, step(f.z * loopOrOnce, 0) * step(0.00001, timeCustom));
    return newUV;
}

float4 SheetUV(half2 sheetIndex, float speed)
{
    float2 offset = float2(1.0 / sheetIndex.x, 1.0 / sheetIndex.y);
    float t = _Time.y * speed;
    float3 f = floor(float3(t, t * offset.x, t * offset.x * offset.y)); //UV根据行列数对号入座
    float4 num = float4(f.x - sheetIndex.x * f.y, -f.y + sheetIndex.y * f.z, offset);

    return num;
}

//拟正交矩阵
float4 Matrix_P2O(float3 posView, float size, float near, float far)
{
    float ascept = (float)_ScreenParams.x / (float)_ScreenParams.y;
    float farSubNear = far - near;
    float farAddNear = far + near;
    float4x4 matrix_p2o = float4x4(1 / (ascept * size), 0, 0, 0,
    0, -1 / size, 0, 0,
    0, 0, 2 / farSubNear, farAddNear / farSubNear,
    0, 0, 0, 1);
    float4 posClip = mul(matrix_p2o, float4(posView, 1));
    return posClip;
}

//拟透视矩阵
float4 Matrix_O2P(float3 posView, float fov, float isZwriteOn)
{
    //float size = UNITY_MATRIX_P._22;
    float2 matrixOffset = isZwriteOn == 0 ? float2(1, 1) : float2(0, -1);
    float far = 2000;
    float near = 0.01;
    float cot = 1.0 / tan(radians(fov) * 0.5);
    float ascept = (float)_ScreenParams.x / (float)_ScreenParams.y;
    float farSubNear = far - near;
    float farAddNear = far + near;
    float4x4 matrix_o2p = float4x4(cot / ascept, 0, 0, 0,
    0, cot * sign(UNITY_MATRIX_P._22), 0, 0,
    0, 0, -farAddNear / farSubNear * matrixOffset.x, -2 * far * near / farSubNear * matrixOffset.y,
    0, 0, -1, 0);
    float4 posClip = mul(matrix_o2p, float4(posView, 1));//[w,0]  ->[-w,w]
    #if UNITY_REVERSED_Z
    #else
        posClip.z = (posClip.w - posClip.z * 2);
    #endif
    
    return posClip;
}

/*
x:输入
Src区间: [s1_,s2_]
Dst区间: [d1_,d2_]
*/
float Remap(float x_, float s1_, float s2_, float d1_, float d2_)
{
    return (x_ - s1_) * (d2_ - d1_) / (s2_ - s1_) + d1_;
}

float Remap(float x, float d1, float d2)
{
    return x * (d2 - d1) + d1;
}

#ifdef _SPLINE_ON
    TEXTURE2D(_SplineMap);
    SAMPLER(sampler_SplineMap);
    float3 _SplineLocalPos;

    float4 SplineDeformMesh(float4 vertex, float3 center, float moveOffset, float4 splineOffset)
    {
        //UI用splineOffset.z为0，非UI用splineOffset.z为1
        float isUI = 1 - splineOffset.z;
        float isNoUI = splineOffset.z;
        float percent = min((1080.0 / 1920.0) * ((float)_ScreenParams.x / (float)_ScreenParams.y), 1);//UI用
        percent = lerp(percent, 1, isNoUI);
        vertex.xy *= percent;
        vertex.z = (vertex.z - UNITY_MATRIX_I_M._34 * isUI);//UI用
        float4 posLocal = vertex;
        posLocal.xyz -= center * isNoUI;//非UI用
        posLocal.xyz = splineOffset.x == 1 ? posLocal.zxy : posLocal.xyz ;
        posLocal.xyz = splineOffset.x == 2 ? posLocal.xzy : posLocal.xyz ;
        float coordinate = posLocal.z * splineOffset.y;
        coordinate = coordinate + moveOffset.x;
        coordinate = lerp(coordinate, frac(coordinate), splineOffset.w);//_SplineOffset.w  环线时使用
        float4 row0 = SAMPLE_TEXTURE2D_LOD(_SplineMap, sampler_SplineMap, float2(coordinate, 0), 0);
        float4 row1 = SAMPLE_TEXTURE2D_LOD(_SplineMap, sampler_SplineMap, float2(coordinate, 1.0 / 3.0), 0);
        float4 row2 = SAMPLE_TEXTURE2D_LOD(_SplineMap, sampler_SplineMap, float2(coordinate, 2.0 / 3.0), 0);
        float4 row3 = float4(0, 0, 0, 1);
        float4x4 mat = float4x4(row0, row1, row2, row3);
        float4 finalvert = mul(mat, posLocal);
        finalvert.xyz -= _SplineLocalPos.xyz * isUI;//UI用
        finalvert.z += UNITY_MATRIX_I_M._34 * isUI;//UI用
        finalvert.xyz += center * isNoUI;//非UI用
        return finalvert;
    }
#endif

//粒子系统使用RT角色的齐次裁剪坐标
float4 ParticleRTRoleClipPos(float3 vertex, float3 center, float2 characterPartSize, float2 characterPartPos)
{
    vertex.y += characterPartSize.y * 5.05;
    center.y += characterPartSize.y * 5.05;
    float3 posView = GetVertexPositionInputs(vertex.xyz).positionVS;
    float3 cenView = GetVertexPositionInputs(center.xyz).positionVS;
    posView.xy = (posView.xy - cenView.xy) * characterPartSize + cenView.xy - characterPartPos * characterPartSize * float2(0.355, 0.353 * 1.79);
    float4 clipPos = mul(UNITY_MATRIX_P, float4(posView, 1));
    return clipPos;
}

//粒子系统使用RT角色的齐次裁剪坐标
float4 ParticleRTRoleClipPos(float3 vertex, float3 center, float2 characterPartSize)
{
    vertex.y += characterPartSize.y * 5.05;
    center.y += characterPartSize.y * 5.05;
    float3 posView = GetVertexPositionInputs(vertex.xyz).positionVS;
    float3 cenView = GetVertexPositionInputs(center.xyz).positionVS;
    posView.xy = (posView.xy - cenView.xy) * characterPartSize + cenView.xy;
    float4 clipPos = mul(UNITY_MATRIX_P, float4(posView, 1));
    return clipPos;
}

//模型使用RT角色的齐次裁剪坐标
float4 MeshRTRoleClipPos(float3 posWorld, float2 characterMeshSize, float2 characterMeshPos)
{
    posWorld.y += characterMeshSize.y * 5.05;
    posWorld.xy -= characterMeshPos * characterMeshSize * float2(0.353, 0.353 * 1.75);
    float4 clipPos = mul(UNITY_MATRIX_VP, float4(posWorld, 1));
    return clipPos;
}

//点阵透明,alpha_XY==1时透明,==0时不透
float ClipAlpha(float clipFactor, float4 screenPosition)
{
    float2 screenPos = screenPosition.xy / screenPosition.w;
    float4 alphaFrac = frac(screenPos.xyxy * float4(0.25, 0.25, 0.5, 0.5));
    float2 alphaIndex = (clipFactor - float2(0.5, 0)) * 10 - alphaFrac.x - 4 * alphaFrac.y;
    float2 alphaHalf = 0.5 - alphaFrac.zw;
    float alpha_XY = step(0, max(alphaIndex.x, 0) + alphaHalf.y * alphaHalf.x * 5) * step(0, alphaIndex.y);
    return alpha_XY;
}
//用于代替smoothstep方法，并且获得的是线性过渡渐变
float4 LinearSmooth(float4 a, float4 b, float4 x)
{
    float4 y = (x - a) / (b - a);
    return saturate(y);
}

//用于代替smoothstep方法，并且获得的是线性过渡渐变
float2 LinearSmooth(float2 a, float2 b, float2 x)
{
    float2 y = (x - a) / (b - a);
    return saturate(y);
}

//用于代替smoothstep方法，并且获得的是线性过渡渐变
float LinearSmooth(float a, float b, float x)
{
    float y = (x - a) / (b - a);
    return saturate(y);
}

float ComputeDepth(float4 posCS_)
{
    #if defined(SHADER_TARGET_GLSL) || defined(SHADER_API_GLES) || defined(SHADER_API_GLES3)
        return ((posCS_.z / posCS_.w) + 1.0) * 0.5;
    #else
        return posCS_.z / posCS_.w;
    #endif
}

#endif
